package com.ld.control.business.task.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ld.control.business.process.model.ProcessExampleModel;
import com.ld.control.business.process.model.ProcessNodeExampleModel;
import com.ld.control.business.process.model.ext.ProcessNodeExampleInfoExt;
import com.ld.control.business.process.service.ProcessExampleService;
import com.ld.control.business.process.service.ProcessNodeExampleService;
import com.ld.control.business.task.mapper.SubTaskExampleMapper;
import com.ld.control.business.task.model.SubTaskExampleModel;
import com.ld.control.business.task.model.TaskExampleModel;
import com.ld.control.business.task.service.SubTaskExampleService;
import com.ld.control.business.task.service.TaskExampleService;
import com.ld.control.business.task.vo.req.SubTaskExampleReqVo;
import com.ld.control.business.task.vo.req.TaskExampleReqVo;
import com.ld.control.business.task.vo.resp.SubTaskExampleRespVo;
import com.ld.control.business.variable.model.VariableModel;
import com.ld.control.business.variable.service.VariableExampleService;
import com.ld.control.business.variable.service.VariableService;
import com.ld.control.business.variable.service.impl.VariableExampleServiceImpl;
import com.ld.control.business.variable.vo.req.VariableExampleReqVo;
import com.ld.control.sysenum.MethodParamTypeEnum;
import com.ld.control.sysenum.ProcessTypeEnum;
import com.ld.control.sysenum.SystemVariableEnum;
import com.ld.control.sysenum.TaskStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 子任务实例表 服务实现类
 * </p>
 *
 * @author wangfeng
 * @since 2024-05-14
 */
@Slf4j
@Service
public class SubTaskExampleServiceImpl extends ServiceImpl<SubTaskExampleMapper, SubTaskExampleModel> implements SubTaskExampleService {

    @Autowired
    private SubTaskExampleMapper subTaskExampleMapper;

    @Autowired
    private ProcessExampleService processExampleService;

    @Autowired
    private ProcessNodeExampleService processNodeExampleService;

    @Autowired
    private VariableExampleService variableExampleService;

    @Autowired
    private TaskExampleService taskExampleService;

    @Autowired
    private VariableService variableService;

    @Transactional
    @Override
    public void add(SubTaskExampleReqVo subTaskExampleReqVo) {
        Long taskExampleId = subTaskExampleReqVo.getTaskExampleId();
        TaskExampleModel taskExampleModel = taskExampleService.getById(taskExampleId);
        SubTaskExampleModel subTaskExampleModel;
        List<Integer> subTaskExampleNumberList = getSubTaskExampleNumber(subTaskExampleReqVo);
        for (int i = 0; i < subTaskExampleNumberList.size(); i++) {
            String subTaskName = subTaskExampleReqVo.getTaskExampleName() + "-" + i;
            subTaskExampleModel = new SubTaskExampleModel();
            subTaskExampleModel.setTaskExampleId(subTaskExampleReqVo.getTaskExampleId());
            subTaskExampleModel.setName(subTaskName);
            subTaskExampleModel.setStatus(TaskStatusEnum.READY.getStatus());
            subTaskExampleModel.setSerialNumber(i);
            subTaskExampleModel.setCreateBy(subTaskExampleReqVo.getCurrentUserAccountId());
            subTaskExampleModel.setCreateTime(new Date());
            subTaskExampleMapper.insert(subTaskExampleModel);

            // 添加系统变量信息，每个子任务的样品数量
            VariableModel variableModel = variableService.getByName(SystemVariableEnum.subTaskSampleSize.getName());
            VariableExampleReqVo variableExampleReqVo = new VariableExampleReqVo();
            variableExampleReqVo.setVariableId(variableModel.getId());
            variableExampleReqVo.setTaskExampleId(subTaskExampleReqVo.getTaskExampleId());
            variableExampleReqVo.setTaskExampleName(taskExampleModel.getName());
            variableExampleReqVo.setTaskExampleCode(taskExampleModel.getCode());
            variableExampleReqVo.setSubTaskExampleId(subTaskExampleModel.getId());
            variableExampleReqVo.setSubTaskExampleName(subTaskName);
            variableExampleReqVo.setName(SystemVariableEnum.subTaskSampleSize.getName());
            variableExampleReqVo.setScope(2);
            variableExampleReqVo.setValueType(MethodParamTypeEnum.INT.getType());
            String value = subTaskExampleNumberList.get(i) + "";
            variableExampleReqVo.setValue(value);
            variableExampleReqVo.setDefaultValue(value);
            variableExampleReqVo.setOffsetFlag(variableModel.getOffsetFlag());
            variableExampleService.add(variableExampleReqVo);
            // 添加subRemainTaskSampleSize
            //variableExampleReqVo.setName(SystemVariableEnum.subRemainTaskSampleSize.getName());
            //variableExampleService.add(variableExampleReqVo);

            //添加子任务实例和流程关系
            processExampleService.addOrdinaryProcess(subTaskExampleReqVo.getTaskExampleId(), subTaskExampleModel.getId(), subTaskExampleReqVo.getTaskTmpId());

        }
    }


    @Override
    public Boolean runSubTaskExample(Long taskExampleId) {
        // 查询任务实例下第一个子任务实例
        QueryWrapper<SubTaskExampleModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SubTaskExampleModel.TASK_EXAMPLE_ID, taskExampleId);
        queryWrapper.orderByAsc(SubTaskExampleModel.SERIAL_NUMBER);
        List<SubTaskExampleModel> subTaskExampleModelList = subTaskExampleMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(subTaskExampleModelList)) {
            return false;
        }
        SubTaskExampleModel subTaskExampleModel = subTaskExampleModelList.get(0);
        return runSubTaskFirstProcess(subTaskExampleModel.getId());
    }

    @Override
    public Boolean runNextSubTaskExample(Long processNodeExampleId) {
        SubTaskExampleModel subTaskExampleModel = getNextSubTaskExampleMByNodeId(processNodeExampleId);
        if (ObjectUtils.isEmpty(subTaskExampleModel)) {
            return false;
        }
        Long subTaskExampleId = subTaskExampleModel.getId();
        return runSubTaskFirstProcess(subTaskExampleId);
    }

    private SubTaskExampleModel getNextSubTaskExampleMByNodeId(Long processNodeExampleId) {
        // 查询此节点的子任务id
        ProcessNodeExampleInfoExt processNodeExampleModelExt = processNodeExampleService.getProcessNodeExampleModelExt(processNodeExampleId);
        ProcessExampleModel processExampleModel = processNodeExampleModelExt.getProcessExampleModel();
        if (processExampleModel.getType() == ProcessTypeEnum.END.getType()) {
            return null;
        }
        if (processExampleModel.getType() == ProcessTypeEnum.INIT.getType()) {
            return getFirstSubTaskExample(processExampleModel.getTaskExampleId());
        }
        if (processExampleModel.getType() == ProcessTypeEnum.ORDINARY.getType()) {
            Long subTaskExampleId = processNodeExampleModelExt.getProcessExampleModel().getSubTaskExampleId();
            SubTaskExampleModel subTaskExampleModel = subTaskExampleMapper.selectById(subTaskExampleId);
            // 找到当前运行节点流程子任务的下一个子任务
            QueryWrapper<SubTaskExampleModel> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(SubTaskExampleModel.TASK_EXAMPLE_ID, subTaskExampleModel.getTaskExampleId());
            queryWrapper.eq(SubTaskExampleModel.SERIAL_NUMBER, subTaskExampleModel.getSerialNumber() + 1);
            return subTaskExampleMapper.selectOne(queryWrapper);
        }
        return null;
    }

    @Override
    public void updateStatusByNodeId(Long processNodeExampleModelId, Integer status) {
        // 查询此节点的子任务id
        ProcessNodeExampleInfoExt processNodeExampleModelExt = processNodeExampleService.getProcessNodeExampleModelExt(processNodeExampleModelId);
        ProcessExampleModel processExampleModel = processNodeExampleModelExt.getProcessExampleModel();
        if (!ObjectUtils.isEmpty(processExampleModel.getSubTaskExampleId())) {
            updateStatus(processExampleModel.getSubTaskExampleId(), status);
        }
    }

    @Override
    public void updateStatus(Long id, Integer status) {
        SubTaskExampleModel subTaskExampleModel = new SubTaskExampleModel();
        subTaskExampleModel.setId(id);
        subTaskExampleModel.setStatus(status);
        subTaskExampleModel.setUpdateTime(new Date());
        if (status == TaskStatusEnum.RUNNING.getStatus()) {
            subTaskExampleModel.setStartTime(new Date());
        }
        if (status == TaskStatusEnum.SUCCESS.getStatus()) {
            subTaskExampleModel.setEndTime(new Date());
        }
        subTaskExampleMapper.updateById(subTaskExampleModel);
    }

    /**
     * 运行某个子任务下第一个流程
     *
     * @param subTaskExampleId
     * @return
     */
    private Boolean runSubTaskFirstProcess(Long subTaskExampleId) {
        // 查询子任务下第一个流程实例
        ProcessExampleModel processExampleModel = processExampleService.getFirstProcessExample(subTaskExampleId);
        if (ObjectUtils.isEmpty(processExampleModel)) {
            return false;
        }
        // 查找流程里面开始节点
        ProcessNodeExampleModel startNodeInfo = processNodeExampleService.getStartNodeInfo(processExampleModel.getId());
        // 将子任务状态变成运行中
        updateStatusByNodeId(startNodeInfo.getId(), TaskStatusEnum.RUNNING.getStatus());
        // 将流程状态修改成运行中
        processExampleService.updateStatus(processExampleModel.getId(), TaskStatusEnum.RUNNING.getStatus());
        // 修改开始节点状态为已完成
        processNodeExampleService.updateNodeStatus(startNodeInfo.getId(), TaskStatusEnum.RUNNING.getStatus());
        processNodeExampleService.updateNodeStatus(startNodeInfo.getId(), TaskStatusEnum.SUCCESS.getStatus());
        // 运行开始节点的下一个节点
        processNodeExampleService.runNextNode(startNodeInfo.getId());
        return true;
    }

    /**
     * 获取任务下面第一个子任务
     *
     * @param taskExampleModelId
     * @return
     */
    @Override
    public SubTaskExampleModel getFirstSubTaskExample(Long taskExampleModelId) {
        QueryWrapper<SubTaskExampleModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SubTaskExampleModel.TASK_EXAMPLE_ID, taskExampleModelId);
        queryWrapper.eq(SubTaskExampleModel.STATUS, TaskStatusEnum.READY.getStatus());
        List<SubTaskExampleModel> subTaskExampleModelList = subTaskExampleMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(subTaskExampleModelList)) {
            return null;
        }
        return subTaskExampleModelList.get(0);
    }

    @Override
    public List<SubTaskExampleRespVo> getListByTaskExampleModelId(Long taskExampleModelId) {
        return subTaskExampleMapper.selectListByTaskExampleModelId(taskExampleModelId);
    }

    //计算N个样品需要执行多少次子实验
    private List<Integer> getSubTaskExampleNumber(SubTaskExampleReqVo reqVo) {
        List<Integer> taskExampleNumberList = new ArrayList<>();
        int number = 0;
        Integer sampleAllSize = reqVo.getSampleAllSize();
        Integer sampleSize = reqVo.getSampleSize();
        number = sampleAllSize / sampleSize;
        for (int i = 0; i < number; i++) {
            taskExampleNumberList.add(sampleSize);
        }
        if (sampleAllSize % sampleSize != 0) {
            taskExampleNumberList.add(sampleAllSize % sampleSize);
        }
        return taskExampleNumberList;
    }

}
